
package net.qiqbframework.common;

import java.util.Optional;
import java.util.function.Predicate;


public abstract class ExceptionUtils {

    private ExceptionUtils() {
    }


    public static Optional<Throwable> findException(Throwable exception, Predicate<Throwable> predicate) {
        Throwable result = exception;
        while (result != null) {
            if (predicate.test(result)) {
                return Optional.of(result);
            } else {
                result = result.getCause();
            }
        }
        return Optional.empty();
    }


    @SuppressWarnings("unchecked")
    public static <T extends Throwable> Optional<T> findException(Throwable exception, Class<T> exceptionClass) {
        return findException(exception, exceptionClass::isInstance).map(e -> (T) e);
    }

    public static boolean isExplicitlyNonTransient(Throwable failure) {
        return failure instanceof ImmutableException
                || (failure.getCause() != null && isExplicitlyNonTransient(failure.getCause()));
    }
}
